package top.lixunda.ecommerce.server.good.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Service;
import top.lixunda.common.utils.ObjectValidators;
import top.lixunda.ecommerce.server.business.BaseServiceImpl;
import top.lixunda.ecommerce.server.business.api.entity.dto.QiNiuFileDatabaseObjectDTO;
import top.lixunda.ecommerce.server.business.api.entity.dto.PageDTO;
import top.lixunda.ecommerce.server.business.api.entity.QiNiuCallbackBody;
import top.lixunda.ecommerce.server.business.api.entity.cache.CacheLoginUser;
import top.lixunda.ecommerce.server.good.api.entity.db.FileCollectionDO;
import top.lixunda.ecommerce.server.good.api.entity.db.QiNiuFileDO;
import top.lixunda.ecommerce.server.good.api.entity.dto.FileCollectionQueryDTO;
import top.lixunda.ecommerce.server.good.api.entity.vo.FileCollectionVO;
import top.lixunda.ecommerce.server.good.config.QiNiuConfig;
import top.lixunda.ecommerce.server.good.mapper.FileCollectionMapper;
import top.lixunda.ecommerce.server.good.mapper.QiNiuFileMapper;
import top.lixunda.ecommerce.server.good.service.IFileCollectionService;

import javax.servlet.http.HttpServletRequest;
import java.time.LocalDateTime;
import java.util.List;

/**
 * <p>
 * 服务实现类,用于保存图片或文件，保存的图片或文件可以多次使用
 * </p>
 *
 * @author Xumda
 * @since 2020-03-24
 */
@Service
public class FileCollectionServiceImpl
        extends BaseServiceImpl<FileCollectionMapper, FileCollectionDO>
        implements IFileCollectionService {

    private final QiNiuConfig qiNiuConfig;

    private final QiNiuFileMapper qiNiuFileMapper;

    @SuppressWarnings("SpringJavaInjectionPointsAutowiringInspection")
    @Autowired
    public FileCollectionServiceImpl(QiNiuConfig qiNiuConfig,
                                     QiNiuFileMapper qiNiuFileMapper) {
        this.qiNiuConfig = qiNiuConfig;
        this.qiNiuFileMapper = qiNiuFileMapper;
    }

    /**
     * 获取当前用户保存的文件
     *
     * @return 文件数据列表
     */
    @Override
    public List<FileCollectionDO> queryCollectionsByUser() {
        CacheLoginUser cacheLoginUser = currentLoginUserCacheNotNull();
        return this.list(new LambdaQueryWrapper<FileCollectionDO>()
                .eq(FileCollectionDO::getCreateUserId, cacheLoginUser.getAccount())
                .eq(FileCollectionDO::getCreateUserType, cacheLoginUser.getType())
                .orderByAsc(FileCollectionDO::getCreateTime));
    }

    /**
     * 根据name获取当前用户保存的文件
     *
     * @return 文件数据列表
     */
    @Override
    public List<FileCollectionDO> queryCollectionsByUserWithName(String name) {
        if (ObjectValidators.isEmpty(name)) {
            throw getAppException("参数不能为空");
        }
        CacheLoginUser cacheLoginUser = currentLoginUserCacheNotNull();
        return this.list(new LambdaQueryWrapper<FileCollectionDO>()
                .eq(FileCollectionDO::getCreateUserId, cacheLoginUser.getAccount())
                .eq(FileCollectionDO::getCreateUserType, cacheLoginUser.getType())
                .eq(FileCollectionDO::getName, name)
                .orderByAsc(FileCollectionDO::getCreateTime));
    }

    /**
     * 根据条件分页查询当前用户保存数据
     *
     * @param wrapper 分页查询参数
     * @return 分页数据
     */
    @Override
    public IPage<FileCollectionDO> queryCollectionByUserWrapper(PageDTO<FileCollectionDO, FileCollectionQueryDTO> wrapper) {
        if (ObjectValidators.isEmpty(wrapper)) {
            throw getAppException("参数不能为空");
        }
        CacheLoginUser cacheLoginUser = currentLoginUserCacheNotNull();
        return this.page(wrapper.getPage(), wrapper.getWrapper(
                innerWrapper -> innerWrapper
                        .eq(FileCollectionDO::getCreateUserId, cacheLoginUser.getAccount())
                        .eq(FileCollectionDO::getCreateUserType, cacheLoginUser.getType())
                        .orderByDesc(FileCollectionDO::getCreateTime)));
    }

    /**
     * 根据id移除数据，权限判断
     *
     * @param ids 编号列表
     * @return 是否移除成功
     */
    @Override
    public boolean removeByIds(List<Integer> ids) {
        if (ObjectValidators.isEmpty(ids)) {
            throw getAppException("参数不能为空");
        }
        CacheLoginUser cacheLoginUser = currentLoginUserCacheNotNull();
        return this.remove(new LambdaUpdateWrapper<FileCollectionDO>()
                .eq(FileCollectionDO::getCreateUserId, cacheLoginUser.getAccount())
                .eq(FileCollectionDO::getCreateUserType, cacheLoginUser.getType())
                .in(FileCollectionDO::getId, ids));
    }

    /**
     * 上传图片回调
     *
     * @param qiNiuCallbackBody 上传文件信息
     * @return 回调数据
     */
    @Override
    public FileCollectionVO uploadFileCallback(QiNiuCallbackBody qiNiuCallbackBody) {
        if (ObjectValidators.isEmpty(qiNiuCallbackBody)) {
            throw getAppException("回调数据为空");
        }
        // 保存七牛回调数据
        CacheLoginUser cacheLoginUser = currentLoginUserCacheNotNull();
        QiNiuFileDatabaseObjectDTO cache = createQiNiuDo(qiNiuCallbackBody,
                cacheLoginUser.getAccount(), cacheLoginUser.getType());
        QiNiuFileDO qiNiuFileDO = new QiNiuFileDO();
        BeanUtils.copyProperties(cache, qiNiuFileDO);
        int count = qiNiuFileMapper.insert(qiNiuFileDO);
        if (count <= 0) {
            throw getAppException("保存上传文件数据失败");
        }
        // 保存文件上传数据
        FileCollectionDO fileCollectionDO = new FileCollectionDO();
        fileCollectionDO.setCreateTime(LocalDateTime.now())
                .setCreateUserId(cacheLoginUser.getAccount())
                .setCreateUserType(cacheLoginUser.getType())
                .setCreateUserName(cacheLoginUser.getName())
                .setFileId(qiNiuFileDO.getId())
                .setFileType(qiNiuFileDO.getMimeType())
                .setVersion(1)
                .setName(ObjectValidators.isNotEmpty(qiNiuFileDO.getParam1())
                        ? qiNiuFileDO.getParam1() : "")
                .setUrl(qiNiuConfig.getBaseUrl() + qiNiuFileDO.getFileKey());
        boolean success = this.save(fileCollectionDO);
        if (!success) {
            throw getAppException("保存上传信息失败！");
        }
        FileCollectionVO fileCollectionVO = new FileCollectionVO();
        fileCollectionVO.setId(fileCollectionDO.getId())
                .setImage(fileCollectionDO.getUrl())
                .setImageFileId(qiNiuFileDO.getId())
                .setQiNiuFileDO(qiNiuFileDO)
                .setFileCollectionDO(fileCollectionDO);
        return fileCollectionVO;
    }

    /**
     * 根据id下载文件
     *
     * @param id      id
     * @param request HttpServletRequest
     * @return ResponseEntity
     */
    @Override
    public ResponseEntity<byte[]> downloadAsFileById(Integer id, HttpServletRequest request) {
        if (ObjectValidators.isEmpty(id)) {
            throw getAppException("参数不能为空");
        }
        FileCollectionDO fileCollectionDO = this.getById(id);
        if (ObjectValidators.isEmpty(fileCollectionDO)) {
            throw getAppException("数据不存在");
        }
        String url = fileCollectionDO.getUrl();
        if (ObjectValidators.isEmpty(url)) {
            throw getAppException("数据错误，url为空");
        }
        return downloadFileByUrl(url, url.substring(url.lastIndexOf("/") + 1), request);
    }
}
